﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Collections;

public partial class cp_Charts_Delta : System.Web.UI.Page
{
    public string Data = "";

    protected void Page_Load(object sender, EventArgs e)
    {
        int thermostatId = Convert.ToInt32(Request["ThermostatId"]);
        ThermostatMonitorLib.Thermostat thermostat = ThermostatMonitorLib.Thermostat.LoadThermostat(thermostatId);
        ThermostatMonitorLib.OutsideConditions conditions = ThermostatMonitorLib.OutsideConditions.LoadOutsideConditionsByLocationId(thermostat.LocationId);
        ThermostatMonitorLib.Temperatures temperatures = ThermostatMonitorLib.Temperatures.LoadRange(thermostat.Id, new DateTime(2000, 1, 1), DateTime.Now);

        DataTable dt = LoadDeltas(conditions, temperatures);
        AddRunTimes(dt, thermostat.Id);
        DataTable data = SumDeltas(dt);
        Output(data);
    }

    private DataTable SumDeltas(DataTable dt)
    {
        Hashtable idleTimes = new Hashtable();
        Hashtable runTimes = new Hashtable();

        foreach (DataRow row in dt.Rows)
        {
            int delta = Convert.ToInt32(row["Delta"]);
            double runTime = Convert.ToDouble(row["RunTime"]);
            double idleTime = Convert.ToDouble(row["IdleTime"]);
            if (idleTimes.ContainsKey(delta))
            {
                idleTimes[delta] = Convert.ToDouble(idleTimes[delta]) + idleTime;
                runTimes[delta] = Convert.ToDouble(runTimes[delta]) + runTime;
            }
            else
            {
                idleTimes[delta] = idleTime;
                runTimes[delta] = runTime;
            }
        }

        DataTable result = new DataTable();
        result.Columns.Add("Delta", typeof(int));
        result.Columns.Add("RunTime", typeof(double));

        foreach (int key in idleTimes.Keys)
        {
            DataRow row = result.NewRow();
            row["Delta"] = key;
            row["RunTime"] = System.Math.Round(Convert.ToDouble(runTimes[key]) / (Convert.ToDouble(runTimes[key]) + Convert.ToDouble(idleTimes[key])) * 100.0,2);
            result.Rows.Add(row);
        }
        return result;
    }

    private void AddRunTimes(DataTable dt, int thermostatId)
    {
        ThermostatMonitorLib.Cycles cycles = ThermostatMonitorLib.Cycles.LoadRange(thermostatId, new DateTime(2000, 1, 1), DateTime.Now);

        foreach (DataRow row in dt.Rows)
        {
            DateTime startTime = Convert.ToDateTime(row["StartTime"]);
            DateTime endTime = Convert.ToDateTime(row["EndTime"]);

            ThermostatMonitorLib.Cycles tempCycles = cycles.GetByTime(startTime, endTime);
            if (cycles.Count > 0)
            {
                double runTime = 0;
                foreach (ThermostatMonitorLib.Cycle cycle in tempCycles)
                {
                    DateTime cycleStart = cycle.StartDate;
                    if (cycleStart < startTime) cycleStart = startTime;
                    DateTime cycleEnd = cycle.EndDate;
                    if (cycleEnd > endTime) cycleEnd = endTime;
                    runTime += new TimeSpan(cycleEnd.Ticks - cycleStart.Ticks).TotalMinutes;
                }
                row["RunTime"] = runTime;
                row["IdleTime"] = Convert.ToDouble(row["IdleTime"]) - runTime;
            }
        }
    }

    private DataTable LoadDeltas(ThermostatMonitorLib.OutsideConditions conditions, ThermostatMonitorLib.Temperatures temperatures)
    {
        int outsideTemp = 999;
        int insideTemp = -999;
        DateTime startTime = DateTime.MinValue;
        DateTime endTime = DateTime.MinValue;

        DataTable sourceDt = CombineTempsAndConditions(conditions, temperatures);
        DataTable result = new DataTable();
        result.Columns.Add("StartTime", typeof(DateTime));
        result.Columns.Add("EndTime", typeof(DateTime));
        result.Columns.Add("Delta", typeof(int));
        result.Columns.Add("RunTime", typeof(double));
        result.Columns.Add("IdleTime", typeof(double));

        sourceDt.DefaultView.Sort = "LogDate";
        foreach (DataRowView sourceRow in sourceDt.DefaultView)
        {
            endTime = Convert.ToDateTime(sourceRow["LogDate"]);
            if (Convert.IsDBNull(sourceRow["OutsideTemp"])) insideTemp = Convert.ToInt32(sourceRow["InsideTemp"]); else outsideTemp = Convert.ToInt32(sourceRow["OutsideTemp"]);
            int delta = outsideTemp - insideTemp;
            if (delta < 100)
            {
                DataRow row = result.NewRow();
                row["StartTime"] = startTime;
                row["EndTime"] = endTime;
                row["Delta"] = delta;
                row["RunTime"] = 0;
                row["IdleTime"] = new TimeSpan(endTime.Ticks - startTime.Ticks).TotalMinutes;
                result.Rows.Add(row);
            }
            startTime = endTime;
        }
        return result;
    }

    private DataTable CombineTempsAndConditions(ThermostatMonitorLib.OutsideConditions conditions, ThermostatMonitorLib.Temperatures temperatures)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("LogDate", typeof(DateTime));
        dt.Columns.Add("OutsideTemp", typeof(int));
        dt.Columns.Add("InsideTemp", typeof(int));

        foreach (ThermostatMonitorLib.OutsideCondition condition in conditions)
        {
            DataRow row = dt.NewRow();
            row["LogDate"] = condition.LogDate;
            row["OutsideTemp"] = condition.Degrees;
            dt.Rows.Add(row);
        }

        foreach (ThermostatMonitorLib.Temperature temp in temperatures)
        {
            DataRow row = dt.NewRow();
            row["LogDate"] = temp.LogDate;
            row["InsideTemp"] = temp.Degrees;
            dt.Rows.Add(row);
        }
        return dt;
    }

    private void Output(DataTable dt)
    {
        dt.DefaultView.Sort = "Delta";
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.Append("data.addRows(" + dt.Rows.Count.ToString() + ");\n");
        for (int i = 0; i < dt.Rows.Count; i++)
        {


            sb.Append("data.setValue(" + i.ToString() + ",0,'" + dt.DefaultView[i]["Delta"].ToString() + "°');\n");
            sb.Append("data.setValue(" + i.ToString() + ",1," + dt.DefaultView[i]["RunTime"].ToString() + ");\n");
        }

        Data = sb.ToString();
        Data += "var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));\n";
        Data += "chart.draw(data, {width: 970, height: 200, scaleType:'maximized', legend:'none', hAxis: { showTextEvery:4 }, chartArea: { width:920 } });";
        ChartDiv.Text = "<div id=\"chart_div\" style=\"width: 970px; height: 200px;\"></div>";
    }
}
